package net.sf.rose.jdbc;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

import net.sf.rose.jdbc.dao.BeanDAO;
import net.sf.rose.jdbc.query.BeanSQL;
import net.sf.rose.jdbc.service.Service;

/**
 * 类说明：数据库基础设置
 * @author fengjian
 * @since 2014/06/24
 */
public class DBUtils {

    /**
     * 功能:根据主键从数据库中符合条件的实体对象
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param entity  - SQL语句
     * @param id      - 主键值
     * @return 记录实体对象
     */
    public static <T> T getBean(Service service, Class<?> entity, String id) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql(id);
        return dao.get();
    }

    /**
     * 功能:根据主键从数据库中符合条件的实体对象
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param entity  - 实体
     * @param key     - 键名
     * @param val     - 键值
     * @return 记录实体对象
     */
    public static <T> T getBean(Service service, Class<?> entity, String key, Object val) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql(key, val);
        return dao.get();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的第一条实体对象
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param bean    - 查询条件
     * @return 记录实体对象
     */
    public static <T> T getBean(Service service, Object bean) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(bean.getClass());
        query.createSql(bean);
        return dao.get();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的记录实体列表
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param entity  - SQL语句
     * @return 记录实体列表
     */
    public static <T> List<T> getBeanList(Service service, Class<?> entity) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql();
        return dao.list();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的记录实体列表
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param entity  - SQL语句
     * @param bean    - 查询条件对象
     * @return 记录实体列表
     */
    public static <T> List<T> getBeanList(Service service, Class<?> entity, Object bean) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql(bean);
        return dao.list();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的记录实体列表
     * @param <T> - 实体类对象类型
     * @param service - 数据库连接服务
     * @param entity  - SQL语句
     * @param map     - 查询条件
     * @return 记录实体列表
     */
    public static <T> List<T> getBeanListByMap(Service service, Class<?> entity, Map<String, Object> map) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql(map);
        return dao.list();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的记录实体列表
     * @param <T> 返回的数据库实体类
     * @param service 数据库连接服务
     * @param entity 实体类对象类型
     * @param key 键名称
     * @param val 键值
     * @return 记录实体列表
     */
    public static <T> List<T> getBeanListByKey(Service service, Class<?> entity, String key, Object val) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.createSql(key, val);
        return dao.list();
    }

    /**
     * 功能:根据查询条件从数据库中符合条件的记录实体列表
     * @param <T> 返回的数据库实体类
     * @param service - 数据库连接服务
     * @param entity  - 实体类对象类型
     * @param sql     - SQL语句
     * @param params  - 查询条件
     * @return 记录实体列表
     */
    public static <T> List<T> getBeanList(Service service, Class<?> entity, String sql, List<Object> params) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.setEntityClass(entity);
        query.setSQL(sql);
        query.setParameters(params);
        return dao.list();
    }

    /**
     * 功能:根据数据库实体类对象更新数据库
     * @param service - 数据库连接服务
     * @param bean    - 数据库实体类对象
     * @return 数据库更新语句执行后影响的行数
     */
    public static int update(Service service, Object bean) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.createSaveSql(bean);
        return dao.update();
    }

    /**
     * 功能:根据数据库实体类对象更新数据库
     * @param service - 数据库连接服务
     * @param bean    - 数据库实体类对象
     * @param forceUpdateProperties    - 强制更新的属性名称，多个以逗号隔开。此参数用于需要更新Null值，或数值是0的情况
     * @return 数据库更新语句执行后影响的行数
     */
    public static int update(Service service, Object bean, String forceUpdateProperties) {
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.createSaveSql(bean, forceUpdateProperties);
        return dao.update();
    }

    /**
     * 功能:根据数据库实体类对象更新数据库
     * @param service - 数据库连接服务
     * @param clazz   - 数据库实体类
     * @param forceUpdateProperties    - 强制更新的属性名称，多个以逗号隔开。此参数用于需要更新Null值，或数值是0的情况
     * @return 数据库更新语句执行后影响的行数
     */
    public static int update(Service service, Class<?> clazz, String forceUpdateProperties) {
    	Object bean = null;
		try {
			bean = clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e.getMessage(), e);
		}
        BeanDAO dao = new BeanDAO(service);
        BeanSQL query = dao.getQuerySQL();
        query.createSaveSql(bean, forceUpdateProperties);
        return dao.update();
    }

    /**
     * 功能:根据数据库实体类对象更新数据库
     * @param service 数据库连接服务
     * @param clazz 数据库实体类
     * @param id 主键值
     * @return 数据库更新语句执行后影响的行数
     */
	public static PageBean delete(Service service, Class<?> clazz, String id) {
		PageBean res = new PageBean();
		BeanDAO dao = new BeanDAO(service);
		BeanSQL query = dao.getQuerySQL();
		query.createDeleteSql(clazz, id);
		if (dao.update() == 0) {
			res.setSuccess(false);
			res.setMessage("没有删除一条记录...");
		}
		return res;
	}

	/**
	 * 功能：根据SQL文和参数集输入阅读式SQL语句
	 * @param sql SQL文
	 * @param list 参数列表
	 * @return SQL文
	 */
	public static String getLog(String sql, List<Object> list) {
		for (Object obj : list) {
			if (obj == null) {
				sql = StringUtils.replaceOnce(sql, "?", "null");
			} else {
				String val = null;
				Class<?> en = obj.getClass();
				val = obj.toString();
				if (en == String.class) {
					val = "'" + val + '\'';
				}
				sql = StringUtils.replaceOnce(sql, "?", val);
			}
		}
		return sql;
	}

}
